﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ElasticAgTest.Models
{
    public delegate void SerialPortReceiveHandler(object sender, byte[] data,int length);
    public class MCUSerial
    {
        public event SerialPortReceiveHandler DataReceived;
        private SerialPort serialPort;
        public bool Connected { get; set; } = false;
        #region 实例化
        private static MCUSerial _instance;
        private static object _lock = new object();
        public static MCUSerial Instance
        {
            get
            {
                if (MCUSerial._instance == null)
                {
                    object @lock = MCUSerial._lock;
                    lock (@lock)
                    {
                        if (MCUSerial._instance == null)
                        {
                            MCUSerial._instance = new MCUSerial();
                        }
                    }
                }
                return MCUSerial._instance;
            }
        }
        #endregion
        public bool Open(string COM)
        {
            try
            {
                serialPort = new SerialPort();
                serialPort.BaudRate = 115200;
                serialPort.Parity = Parity.None;
                serialPort.DataBits = 8;
                serialPort.StopBits = StopBits.One;
                serialPort.DataReceived += mCUSerialPort_DataReceived;
                serialPort.PortName = COM;
                serialPort.NewLine = "\r\n";
                serialPort.Open();
                serialPort.DiscardInBuffer();
                serialPort.DiscardOutBuffer();
                serialPort.WriteTimeout = 5000;
                serialPort.ReadTimeout = 5000;
                Connected = true;
                return true;
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
                Connected = false;
                return false;
            }
        }
        //private int _index = 0;
        private void mCUSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                //Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss.fff") + $"中断{_index}");

                string result = serialPort.ReadLine().Replace("\r\n", string.Empty);
                int NumberChars = result.Length;
                byte[] bytes = new byte[NumberChars / 2];
                for (int i = 0; i < NumberChars; i += 2)
                    bytes[i / 2] = Convert.ToByte(result.Substring(i, 2), 16);                
                if (DataReceived != null)
                {
                    DataReceived(this, bytes, NumberChars / 2);
                }

                //byte[] array1 = new byte[2046];
                //int index = 0;
                //while (index < RecCount)
                //{
                //    int bytesToRead = serialPort.BytesToRead;
                //    byte[] array = new byte[bytesToRead];
                //    serialPort.Read(array, 0, bytesToRead);
                //    array.CopyTo(array1, index);
                //    index += bytesToRead;
                //    if (RecCount > 4)
                //    {
                //        System.Threading.Thread.Sleep(100);
                //    }
                //}
                //if (DataReceived != null)
                //{
                //    //Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss.fff")  + $"→{index}");
                //    byte[] array2 = new byte[2046];
                //    array1.CopyTo(array2, 0);
                //    DataReceived(this, array2, index);
                //}
                //Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss.fff") + $"中断结束{_index}");
                //_index++;
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }
        public bool WriteMCURegister(int addr, int val)
        {
            try
            {
                byte[] data0 = new byte[2] { 0x01, 0x06 };
                data0 = data0.Concat(BitConverter.GetBytes((ushort)addr).Reverse()).ToArray();
                data0 = data0.Concat(BitConverter.GetBytes((ushort)val).Reverse()).ToArray();
                var crc = CRC16.N_CRC16(data0, data0.Length);
                byte[] crc1 = BitConverter.GetBytes((ushort)crc);
                data0 = data0.Concat(crc1).ToArray();
                serialPort.Write(data0, 0, data0.Length);
                return true;
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
                return false;
            }
        }
    }
}
